package com.itheima.springbootwebbtalis.aspect;

import com.itheima.springbootwebbtalis.mapper.EmpLoginLogMapper;
import com.itheima.springbootwebbtalis.pojo.Emp;
import com.itheima.springbootwebbtalis.pojo.EmpLoginLog;
import com.itheima.springbootwebbtalis.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Map;

@Slf4j
@Component
@Aspect
public class EmpLoginLogAspect {
    @Autowired
    private EmpLoginLogMapper empLoginLogMapper;
    // 切入点表达式：只需要对一个登录方法进行增强（建议使用execution）
    // 通知类型：环绕通知
    @Around("execution(* com.itheima.springbootwebbtalis.controller.loginController.login(com.itheima.springbootwebbtalis.pojo.Emp))")
    public Object recordLoginLog(ProceedingJoinPoint joinPoint) throws Throwable {
       // 获取目标方法执行耗时，借助环绕通知的灵活性获取
        long start = System.currentTimeMillis();
        Object result = null;
        try{
            // 执行目标方法开始
            result = joinPoint.proceed();
            // 执行目标方法结束
        }catch(Exception e){
            result=Result.error(e.getMessage());// 异常情况，自行构建异常对象
        }finally {    // finally保证：不管登录成功还是失败，都要保存日志
            long end = System.currentTimeMillis();
            long costTime = end - start;

            // b.获取令牌，获取目标方法login登录结果，从Result中获取令牌
            Result result2 = (Result) result;
            Map map = (Map)result2.getData(); // 获取result的data数据


            String token = "";
            if(map != null){  // 进行非null判断原因：登录事变，没有data，无法获取data中的token，因此需要排除失败的情况
                token = (String) map.get("token");
            }
            // c.获取登录结果，获取目标方法login登录结果
            int code = (Integer) result2.getCode();
            short isSuccess =(short) code;

            // d.获取请求参数，通过连接点对象ProceedingJoinPoint，获取目标方法参数
            Emp emp = (Emp)joinPoint.getArgs()[0];

            // 1.定义操作日志对象，手机操作日志信息
            EmpLoginLog e = new EmpLoginLog();
            // 通过连接点对象ProceedingJoinPoint，获取目标方法信息
            e.setLoginTime(LocalDateTime.now());
            e.setUsername(emp.getUsername());
            e.setPassword(emp.getPassword());
            e.setIsSuccess(isSuccess);
            e.setJwt(token);
            e.setCostTime(costTime);
            // 2.调用操作日志的持久层接口，添加日志信息到操作日志表中
            empLoginLogMapper.insert(e);
        }
        return result;
    }
}
